﻿// CBattleUI.cs
// Author: Gant Briseno
#region Using Statements
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Casters.source.Managers;
using Casters.source.Objects;
#endregion

namespace Casters.source.States.UIs
{
    public class CBattleUI : CBaseUI
    {
        // Used for the Lists of windows
        public enum UIWindowTop { Back, Menu, Chat, Camera, Help, Ticker, Move, EndTurn, Max };
        public enum UIWindowBottom { Move, Combat, EndTurn, Max };
        public enum UIWindowSpell { Slot1, Slot2, Slot3, Slot4, Slot5, Slot6, Max };
        public enum UIWindowReadyCheck { Confirm, Cancel, Max };

        /// <summary>
        /// Used to Display a window on the ui
        /// </summary>
        protected class WindowStruct
        {
            // Window image to use
            public Texture2D m_image;

            // Where to draw it
            public Rectangle m_rDestination;

            // Text to go on the image
            public string m_string;

            // What type of window it is
            public UIWindowTop m_type;
            public UIWindowBottom m_typeBot;
            public UIWindowSpell m_typeSpell;
            public UIWindowReadyCheck m_typeReady;

            /// <summary>
            /// Sets up the Window at the top of the screen
            /// </summary>
            /// <param name="type"></param>
            public WindowStruct(UIWindowTop type)
            {
                m_image = null;
                m_rDestination = Rectangle.Empty;
                m_type = type;
                m_string = "";
            }

            /// <summary>
            /// Sets up the Window at the bottom of the screen
            /// </summary>
            /// <param name="type"></param>
            public WindowStruct(UIWindowBottom type)
            {
                m_image = null;
                m_rDestination = Rectangle.Empty;
                m_typeBot = type;
                m_string = "";
            }

            /// <summary>
            /// Sets up a Window for the Spell list
            /// </summary>
            /// <param name="type"></param>
            public WindowStruct(UIWindowSpell type)
            {
                m_image = null;
                m_rDestination = Rectangle.Empty;
                m_typeSpell = type;
                m_string = "";
            }

            public WindowStruct(UIWindowReadyCheck type)
            {
                m_image = null;
                m_rDestination = Rectangle.Empty;
                m_typeReady = type;
                m_string = "";
            }
        }

        // 2D list for dynamic menus
        protected List<List<WindowStruct>> m_ListOfWindowsTop;

        // Single dynamic array of Windows
        protected List<WindowStruct> m_ListOfWindowsBottom;
        protected List<WindowStruct> m_ListOfSpells;

        // Pop up 2 windows to Confirm or Cancel an action
        protected List<WindowStruct> m_ListOfReadyCheck;

        // Variables
        protected Vector2 m_CameraOffset;
        protected SpriteFont m_Font;
        protected bool m_bUIClicked = false;


        // Accessor
        public bool GetUIClicked() { return m_bUIClicked; }

        /// <summary>
        /// Create the lists
        /// </summary>
        public CBattleUI()
        {
            m_ListOfWindowsTop = new List<List<WindowStruct>>();
            m_ListOfWindowsBottom = new List<WindowStruct>();
            m_ListOfSpells = new List<WindowStruct>();
            m_ListOfReadyCheck = new List<WindowStruct>();

            for (int i = 0; i < (int)UIWindowTop.Max; ++i)
                m_ListOfWindowsTop.Add(new List<WindowStruct>());
        }

        /// <summary>
        /// Fill out the lists and initialize them
        /// </summary>
        public override void Initialize()
        {
            Vector2 viewport = CGame.GetInstance().viewPort;

            for (int i = 0; i < (int)UIWindowTop.Max; ++i)
                m_ListOfWindowsTop[i].Add(new WindowStruct((UIWindowTop)i));

            float YoffsetTop = 0.01f;
            int TopHeight = 30;
            m_ListOfWindowsTop[(int)UIWindowTop.Back][0].m_rDestination = new Rectangle(100, (int)(viewport.Y * YoffsetTop), 100, TopHeight);
            m_ListOfWindowsTop[(int)UIWindowTop.Menu][0].m_rDestination = new Rectangle(200, (int)(viewport.Y * YoffsetTop), 100, TopHeight);
            m_ListOfWindowsTop[(int)UIWindowTop.Chat][0].m_rDestination = new Rectangle(300, (int)(viewport.Y * YoffsetTop), 100, TopHeight);
            m_ListOfWindowsTop[(int)UIWindowTop.Camera][0].m_rDestination = new Rectangle(400, (int)(viewport.Y * YoffsetTop), 100, TopHeight);
            m_ListOfWindowsTop[(int)UIWindowTop.Help][0].m_rDestination = new Rectangle(500, (int)(viewport.Y * YoffsetTop), 100, TopHeight);
            m_ListOfWindowsTop[(int)UIWindowTop.Ticker][0].m_rDestination = new Rectangle(600, (int)(viewport.Y * YoffsetTop), 580, TopHeight);
            m_ListOfWindowsTop[(int)UIWindowTop.Back][0].m_string = "Back";
            m_ListOfWindowsTop[(int)UIWindowTop.Menu][0].m_string = "Menu";
            m_ListOfWindowsTop[(int)UIWindowTop.Chat][0].m_string = "Chat";
            m_ListOfWindowsTop[(int)UIWindowTop.Camera][0].m_string = "Camera";
            m_ListOfWindowsTop[(int)UIWindowTop.Help][0].m_string = "Help";
            m_ListOfWindowsTop[(int)UIWindowTop.Ticker][0].m_string = "Ticker Info Will Go Here!";

            LoadMCE();
        }

        /// <summary>
        /// Load images and register events
        /// </summary>
        public override void LoadContent()
        {
            Texture2D image = CGame.GetInstance().Content.Load<Texture2D>("Menu/menu_window");
            for(int i = 0; i < (int)UIWindowTop.Max; ++i)
                m_ListOfWindowsTop[i][0].m_image = image;

            m_Font = CGame.GetInstance().Content.Load<SpriteFont>("Fonts/Arial");

            CEventSystem.RegisterEventHandler(EventID.MouseLeftClick, OnMouseClick);
        }

        /// <summary>
        /// Free up memory and unregister events
        /// </summary>
        public override void UnloadContent()
        {
            for (int i = 0; i < (int)UIWindowTop.Max; ++i)
                m_ListOfWindowsTop[i][0].m_image = null;

            UnloadMCE();

            CEventSystem.UnregisterEventHandler(EventID.MouseLeftClick, OnMouseClick);
        }

        public override void Update(float _dt)
        {
            m_bUIClicked = false;
        }

        /// <summary>
        /// Draw all the UI windows to the screen
        /// </summary>
        public override void Draw()
        {
            Rectangle temp;

            m_CameraOffset = CGame.GetInstance().m_Camera.m_vPosition;
            for(int i = 0; i < m_ListOfWindowsTop.Count; ++i)
            {
                temp.X = (int)(m_ListOfWindowsTop[i][0].m_rDestination.X + m_CameraOffset.X);
                temp.Y = (int)(m_ListOfWindowsTop[i][0].m_rDestination.Y + m_CameraOffset.Y);
                temp.Width = m_ListOfWindowsTop[i][0].m_rDestination.Width;
                temp.Height = m_ListOfWindowsTop[i][0].m_rDestination.Height;
                CRenderEngine.Draw(m_ListOfWindowsTop[i][0].m_image, temp, Color.Beige);

                Vector2 pos = new Vector2(temp.X + 5, temp.Y + 5);
                CRenderEngine.DrawString(m_Font, m_ListOfWindowsTop[i][0].m_string, pos, Color.Black);
            }

            for (int i = 0; i < m_ListOfWindowsBottom.Count; ++i)
            {
                temp.X = (int)(m_ListOfWindowsBottom[i].m_rDestination.X + m_CameraOffset.X);
                temp.Y = (int)(m_ListOfWindowsBottom[i].m_rDestination.Y + m_CameraOffset.Y);
                temp.Width = m_ListOfWindowsBottom[i].m_rDestination.Width;
                temp.Height = m_ListOfWindowsBottom[i].m_rDestination.Height;
                CRenderEngine.Draw(m_ListOfWindowsBottom[i].m_image, temp, Color.Beige);

                Vector2 pos = new Vector2(temp.X + 5, temp.Y + 5);
                CRenderEngine.DrawString(m_Font, m_ListOfWindowsBottom[i].m_string, pos, Color.Black);
            }

            //int playerTurn = CBattleState.GetInstance().GetTurnNum() % 2;
            for (int i = 0; i < m_ListOfSpells.Count; ++i)
            {
                temp.X = (int)(m_ListOfSpells[i].m_rDestination.X + m_CameraOffset.X);
                temp.Y = (int)(m_ListOfSpells[i].m_rDestination.Y + m_CameraOffset.Y);
                temp.Width = m_ListOfSpells[i].m_rDestination.Width;
                temp.Height = m_ListOfSpells[i].m_rDestination.Height;
                CRenderEngine.Draw(m_ListOfSpells[i].m_image, temp, Color.Beige);

                Vector2 pos = new Vector2(temp.X + 5, temp.Y + 5);
                CRenderEngine.DrawString(m_Font, m_ListOfSpells[i].m_string, pos, Color.Black);
            }
            

            
            for (int i = 0; i < m_ListOfReadyCheck.Count; ++i)
            {
                temp.X = (int)(m_ListOfReadyCheck[i].m_rDestination.X + m_CameraOffset.X);
                temp.Y = (int)(m_ListOfReadyCheck[i].m_rDestination.Y + m_CameraOffset.Y);
                temp.Width = m_ListOfReadyCheck[i].m_rDestination.Width;
                temp.Height = m_ListOfReadyCheck[i].m_rDestination.Height;
                CRenderEngine.Draw(m_ListOfReadyCheck[i].m_image, temp, Color.Beige);

                Vector2 pos = new Vector2(temp.X + 5, temp.Y + 5);
                CRenderEngine.DrawString(m_Font, m_ListOfReadyCheck[i].m_string, pos, Color.Black);
            }
            
        }

        /// <summary>
        /// Used to load/unload specific parts of the UI
        /// 
        /// This will handle the dynamic menus
        /// </summary>
        /// <param name="newPhase"></param>
        public void ChangePhase(CBattleState.BattlePhase newPhase)
        {
        }

        public void LoadMCE()
        {
            Texture2D image = CGame.GetInstance().Content.Load<Texture2D>("Menu/menu_window");
            Vector2 viewport = CGame.GetInstance().viewPort;
            float YoffsetBottom = 0.87f;

            for (int i = 0; i < (int)UIWindowBottom.Max; ++i)
                m_ListOfWindowsBottom.Add(new WindowStruct((UIWindowBottom)i));

            for (int i = 0; i < (int)UIWindowBottom.Max; ++i)
                m_ListOfWindowsBottom[i].m_image = image;

            m_ListOfWindowsBottom[(int)UIWindowBottom.Move].m_rDestination = new Rectangle(1150, (int)(viewport.Y * YoffsetBottom), 80, 80);
            m_ListOfWindowsBottom[(int)UIWindowBottom.Combat].m_rDestination = new Rectangle(1150 - 80, (int)(viewport.Y * YoffsetBottom), 80, 80);
            m_ListOfWindowsBottom[(int)UIWindowBottom.EndTurn].m_rDestination = new Rectangle(1150 - 160, (int)(viewport.Y * YoffsetBottom), 80, 80);
            m_ListOfWindowsBottom[(int)UIWindowBottom.Move].m_string = "Move";
            m_ListOfWindowsBottom[(int)UIWindowBottom.Combat].m_string = "Combat";
            m_ListOfWindowsBottom[(int)UIWindowBottom.EndTurn].m_string = "End\nTurn";
        }

        public void UnloadMCE()
        {
            m_ListOfWindowsBottom.Clear();
        }

        public void LoadSpells(CPlayer player)
        {
            Texture2D image = CGame.GetInstance().Content.Load<Texture2D>("Menu/menu_window");
            Vector2 viewport = CGame.GetInstance().viewPort;
            float YoffsetBottom = 0.87f;
            int spellIndex;

            for (int i = 0; i < (int)UIWindowSpell.Max; ++i)
            {
                m_ListOfSpells.Add(new WindowStruct((UIWindowSpell)i));
                m_ListOfSpells[i].m_image = image;
                
                spellIndex = player.m_SpellSlots[i];
                m_ListOfSpells[i].m_string = CSpellManager.GetInstance().GetSpell(spellIndex).GetName();
                m_ListOfSpells[i].m_rDestination = new Rectangle((int)(viewport.X * 0.5f - 300) + (100 * i), (int)(viewport.Y * YoffsetBottom), 100, 100);
            }
        }

        public void UnloadSpells()
        {
            m_ListOfSpells.Clear();
        }

        public void LoadReadyCheck(bool showConfirm = true, bool showCancel = true)
        {
            Texture2D image = CGame.GetInstance().Content.Load<Texture2D>("Menu/menu_window");
            Vector2 viewport = CGame.GetInstance().viewPort;
            float YoffsetBottom = 0.87f;
            for (int i = 0; i < (int)UIWindowReadyCheck.Max; ++i)
            {
                
                WindowStruct temp = new WindowStruct((UIWindowReadyCheck)i);
                temp.m_image = image;
                switch ((UIWindowReadyCheck)i)
                {
                    case UIWindowReadyCheck.Confirm:
                        if(showConfirm == false)
                            continue;
                        temp.m_string = "Confirm";
                        break;
                    case UIWindowReadyCheck.Cancel:
                        if(showCancel == false)
                            continue;
                        temp.m_string = "Cancel";
                        break;
                }
                temp.m_rDestination = new Rectangle((int)(viewport.X * 0.5f - 100) + (100 * i), (int)(viewport.Y * YoffsetBottom) - 110, 100, 100);
                m_ListOfReadyCheck.Add(temp);
            }
        }

        public void UnloadReadyCheck()
        {
            m_ListOfReadyCheck.Clear();
        }

        //********* EVENTS *********\\
        public void OnMouseClick(params object[] eventArgs)
        {
            Point mousePos = new Point((int)((Vector2)eventArgs[0]).X, (int)((Vector2)eventArgs[0]).Y);
            Rectangle temp = Rectangle.Empty;

            for (int i = 0; i < m_ListOfWindowsTop.Count; ++i)
            {
                temp.X = (int)(m_ListOfWindowsTop[i][0].m_rDestination.X + m_CameraOffset.X);
                temp.Y = (int)(m_ListOfWindowsTop[i][0].m_rDestination.Y + m_CameraOffset.Y);
                temp.Width = m_ListOfWindowsTop[i][0].m_rDestination.Width;
                temp.Height = m_ListOfWindowsTop[i][0].m_rDestination.Height;
                if (temp.Contains(mousePos))
                {
                    switch (m_ListOfWindowsTop[i][0].m_type)
                    {
                        case UIWindowTop.Back:
                            break;
                        case UIWindowTop.Menu:
                            break;
                        case UIWindowTop.Chat:
                            break;
                        case UIWindowTop.Camera:
                            break;
                        case UIWindowTop.Help:
                            break;
                        case UIWindowTop.Ticker:
                            break;
                    }

                    m_bUIClicked = true;
                    return;
                }
            }

            for (int i = 0; i < m_ListOfWindowsBottom.Count; ++i)
            {
                temp.X = (int)(m_ListOfWindowsBottom[i].m_rDestination.X + m_CameraOffset.X);
                temp.Y = (int)(m_ListOfWindowsBottom[i].m_rDestination.Y + m_CameraOffset.Y);
                temp.Width = m_ListOfWindowsBottom[i].m_rDestination.Width;
                temp.Height = m_ListOfWindowsBottom[i].m_rDestination.Height;
                if (temp.Contains(mousePos))
                {
                    switch (m_ListOfWindowsBottom[i].m_typeBot)
                    {
                        case UIWindowBottom.Move:
                            CEventSystem.BroadcastEvent(EventID.BattleUI_MoveClicked);
                            break;
                        case UIWindowBottom.Combat:
                            CEventSystem.BroadcastEvent(EventID.BattleUI_CombatClicked);
                            break;
                        case UIWindowBottom.EndTurn:
                            CEventSystem.BroadcastEvent(EventID.BattleUI_EndTurnClicked);
                            break;
                    }

                    m_bUIClicked = true;
                    return;
                }
            }

            
            for (int i = 0; i < m_ListOfSpells.Count; ++i)
            {
                temp.X = (int)(m_ListOfSpells[i].m_rDestination.X + m_CameraOffset.X);
                temp.Y = (int)(m_ListOfSpells[i].m_rDestination.Y + m_CameraOffset.Y);
                temp.Width = m_ListOfSpells[i].m_rDestination.Width;
                temp.Height = m_ListOfSpells[i].m_rDestination.Height;

                if (temp.Contains(mousePos))
                {
                    CEventSystem.BroadcastEvent(EventID.BattleUI_SpellClicked, i);
                    m_bUIClicked = true;
                    return;
                }
            }
            

           
            for (int i = 0; i < m_ListOfReadyCheck.Count; ++i)
            {
                temp.X = (int)(m_ListOfReadyCheck[i].m_rDestination.X + m_CameraOffset.X);
                temp.Y = (int)(m_ListOfReadyCheck[i].m_rDestination.Y + m_CameraOffset.Y);
                temp.Width = m_ListOfReadyCheck[i].m_rDestination.Width;
                temp.Height = m_ListOfReadyCheck[i].m_rDestination.Height;

                if (temp.Contains(mousePos))
                {
                    switch (m_ListOfReadyCheck[i].m_typeReady)
                    {
                        case UIWindowReadyCheck.Confirm:
                            CEventSystem.BroadcastEvent(EventID.Confirm);
                            break;
                        case UIWindowReadyCheck.Cancel:
                            CEventSystem.BroadcastEvent(EventID.Back);
                            break;
                    }

                    m_bUIClicked = true;
                    return;
                }
            }
        }
    }
}
